﻿
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;

namespace MyFloridaHouse.libSvOpenDistricts.Criteria
{


    public class CriteriaDatasetDTO : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        private enumCriteriaType _criteriaType = enumCriteriaType.Total;
        public enumCriteriaType criteriaType
        {
            get { return _criteriaType; }
            set { if (_criteriaType != value) { _criteriaType = value; NotifyPropertyChanged("criteriaType"); } }
        }

        private bool _isSelected = false;
        public bool isSelected
        {
            get { return _isSelected; }
            set { if (_isSelected != value) { _isSelected = value; NotifyPropertyChanged("isSelected"); } }
        }

        private bool _isQueryCriteria = true;
        public bool isQueryCriteria
        {
            get { return _isQueryCriteria; }
            set { if (_isQueryCriteria != value) { _isQueryCriteria = value; NotifyPropertyChanged("isQueryCriteria"); } }
        }
        private string _criteriaName = "not found";
        public string criteriaName
        {
            get { return _criteriaName; }
            set { if (_criteriaName != value) { _criteriaName = value; } }
        }
        private string _criteriaHeader = "tempHeader";
        public string criteriaHeader
        {
            get { return _criteriaHeader; }
            set { if (_criteriaHeader != value) { _criteriaHeader = value; } }
        }
        private string _description = "TempDescription";
        public string description
        {
            get { return _description; }
            set { if (_description != value) { _description = value; } }
        }

        private int _valueMin = 0;
        public int valueMin
        {
            get { return _valueMin; }
            set { if (_valueMin != value) { _valueMin = value; NotifyPropertyChanged("valueMin"); } }
        }

        private int _valueMax = 100;
        public int valueMax
        {
            get { return _valueMax; }
            set { if (_valueMax != value) { _valueMax = value; NotifyPropertyChanged("valueMax"); } }
        }

        private int _queryMin = 0;
        public int queryMin
        {
            get { return _queryMin; }
            set { if (_queryMin != value) { _queryMin = value; NotifyPropertyChanged("queryMin"); NotifyPropertyChanged("pctQueryMin"); } }
        }

        private int _queryMax = 0;
        public int queryMax
        {
            get { return _queryMax; }
            set { if (_queryMax != value) { _queryMax = value; NotifyPropertyChanged("queryMax"); NotifyPropertyChanged("pctQueryMax"); } }
        }


        public int pctQueryMin
        {
            get 
            {
                if (range == 0)  return 0;
                return (int)((((double)queryMin - (double)offset) / ((double)range)) * 100.0); 
            }
            // this happens when the user slides the lower slider bar
            set
            {
                if (pctQueryMin != value)
                {
                    if (range == 0)
                    {
                        queryMin = 0;
                        return;
                    }

                    queryMin = (int)((double)value / 100.0 * (double)range) + offset;
                }
            }

        }

        public int pctQueryMax
        {
            get 
            {
                if (range == 0) return 100;
                return (int) ( (( (double)queryMax - (double) offset) / ((double) range)) * 100.0); 
            }
            // this happens when the user slides the upper slider bar
            set
            {
                if (pctQueryMax != value)
                {
                    if (range == 0)
                    {
                        queryMax = 100;
                        return;
                    }

                    queryMax = (int)((double)value / 100.0 * (double)range) + offset;
                }
            }
        }

        private List<CriteriaDictionaryDTO> _dictionaryList;
        public List<CriteriaDictionaryDTO> dictionaryList
        {

            get { return _dictionaryList; }
            set { if (_dictionaryList != value) { _dictionaryList = value; NotifyPropertyChanged("dictionaryList");} }
        }


        #region computed values
        public int pctValueMin
        {
            get { return 0; }
        }
        public int pctValueMax
        {
            get { return 100; }
        }
        public int range
        {
            get 
            {
                    return valueMax - valueMin; 
            }
        }
        public int offset
        {
            get 
            {
               return valueMin;
            }
        }
        #endregion

        public static CriteriaDatasetDTO BuildCriteriaForTotal(string dataName, string header, string description, bool isQueryCriteria, int layerID_1, int dictionaryID_1)
        {
            CriteriaDatasetDTO newCriteriaDatasetDTO = new CriteriaDatasetDTO();
            newCriteriaDatasetDTO.criteriaName = dataName;
            newCriteriaDatasetDTO.criteriaHeader = header;
            newCriteriaDatasetDTO.description = description;
            newCriteriaDatasetDTO.isQueryCriteria = isQueryCriteria;
            newCriteriaDatasetDTO.queryMin = 0;
            newCriteriaDatasetDTO.queryMax = 10000000;
            newCriteriaDatasetDTO.criteriaType = enumCriteriaType.Total;
            newCriteriaDatasetDTO.dictionaryList = new List<CriteriaDictionaryDTO>();
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_1, dictionaryID_1, newCriteriaDatasetDTO.CriteriaDictionaryPropertyChangedHandler));
            return newCriteriaDatasetDTO;
        }

        public static CriteriaDatasetDTO BuildCriteriaForTotalDifference(string dataName, string header, string description, bool isQueryCriteria, int layerID_1, int dictionaryID_1, int layerID_2, int dictionaryID_2)
        {
            CriteriaDatasetDTO newCriteriaDatasetDTO = new CriteriaDatasetDTO();
            newCriteriaDatasetDTO.isQueryCriteria = isQueryCriteria;
            newCriteriaDatasetDTO.criteriaName = dataName;
            newCriteriaDatasetDTO.criteriaHeader = header;
            newCriteriaDatasetDTO.description = description;
            newCriteriaDatasetDTO.queryMin = 0;
            newCriteriaDatasetDTO.queryMax = 10000000;
            newCriteriaDatasetDTO.criteriaType = enumCriteriaType.TotalDifference;
            newCriteriaDatasetDTO.dictionaryList = new List<CriteriaDictionaryDTO>();
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_1, dictionaryID_1, newCriteriaDatasetDTO.CriteriaDictionaryPropertyChangedHandler));
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_2, dictionaryID_2, newCriteriaDatasetDTO.CriteriaDictionaryPropertyChangedHandler));
            return newCriteriaDatasetDTO;
        }

        public static CriteriaDatasetDTO BuildCriteriaForTotalDifferenceRelativeMagnitude(string dataName, string header, string description, bool isQueryCriteria, int layerID_1, int dictionaryID_1, int layerID_2, int dictionaryID_2)
        {
            CriteriaDatasetDTO newDTO = CriteriaDatasetDTO.BuildCriteriaForTotalDifference( dataName,  header,  description,  isQueryCriteria,  layerID_1,  dictionaryID_1,  layerID_2,  dictionaryID_2);
            newDTO.criteriaType = enumCriteriaType.TotalDifferenceRelativeMagnitude;
            return newDTO;
        }

        public static CriteriaDatasetDTO BuildCriteriaForPercent(string dataName, string header, string description, bool isQueryCriteria, int layerID_1, int dictionaryID_1, int layerID_2, int dictionaryID_2)
        {
            CriteriaDatasetDTO newCriteriaDatasetDTO = new CriteriaDatasetDTO();
            newCriteriaDatasetDTO.criteriaName = dataName;
            newCriteriaDatasetDTO.criteriaHeader = header;
            newCriteriaDatasetDTO.description = description;
            newCriteriaDatasetDTO.isQueryCriteria = isQueryCriteria;
            newCriteriaDatasetDTO.queryMin = 0;
            newCriteriaDatasetDTO.queryMax = 100;
            newCriteriaDatasetDTO.criteriaType = enumCriteriaType.Percent;
            newCriteriaDatasetDTO.dictionaryList = new List<CriteriaDictionaryDTO>();
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_1, dictionaryID_1, null));
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_2, dictionaryID_2, null));
            return newCriteriaDatasetDTO;
        }

        public static CriteriaDatasetDTO BuildCriteriaForPercentDifference(string dataName, string header, string description, bool isQueryCriteria, int layerID_1, int dictionaryID_1, int layerID_2, int dictionaryID_2, int layerID_3, int dictionaryID_3, int layerID_4, int dictionaryID_4)
        {
            CriteriaDatasetDTO newCriteriaDatasetDTO = new CriteriaDatasetDTO();
            newCriteriaDatasetDTO.criteriaName = dataName;
            newCriteriaDatasetDTO.criteriaHeader = header;
            newCriteriaDatasetDTO.description = description;
            newCriteriaDatasetDTO.isQueryCriteria = isQueryCriteria;
            newCriteriaDatasetDTO.queryMin = 0;
            newCriteriaDatasetDTO.queryMax = 100;
            newCriteriaDatasetDTO.criteriaType = enumCriteriaType.PercentDifference;
            newCriteriaDatasetDTO.dictionaryList = new List<CriteriaDictionaryDTO>();
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_1, dictionaryID_1, null));
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_2, dictionaryID_2, null));
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_3, dictionaryID_3, null));
            newCriteriaDatasetDTO.dictionaryList.Add(new CriteriaDictionaryDTO(layerID_4, dictionaryID_4, null));
            return newCriteriaDatasetDTO;
        }

        // When a dictionary min or max changes, we need to update the criteria min/max to match it.
        // percent and percent difference is always 0 minimum; so they stay at the default
        // percent and percent maximum is always 100 maximum; so they stay at the default
        public void CriteriaDictionaryPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
        {
            CriteriaDictionaryDTO critDictionaryItem = (CriteriaDictionaryDTO)sender;
            
            if (criteriaType==enumCriteriaType.Total)
            {
                valueMin = dictionaryList[0].min;
                valueMax = dictionaryList[0].max;
            }

            else if (criteriaType == enumCriteriaType.TotalDifference)
            {
                valueMin = dictionaryList[0].min - dictionaryList[1].max;
                valueMax = dictionaryList[0].max - dictionaryList[1].min;

            }
        }


    }

}
